#coding=utf-8
'''
基本功能：自动生成java文件:包括service,serviceImpl,mapper,entity,controller,dubbo,xml等文件
作者：王杰
创建时间： 2018年8月8日
'''

import os,zipfile,re
import json
import time
import tarfile
from flask import Flask, render_template, send_from_directory, request

app = Flask(__name__)


@app.route('/')
def index():
    return render_template('create_class.html')


@app.route("/download/<path_dir_name>/<filename>", methods=['GET'])
def downloader(path_dir_name, filename):
    # 指定文件下载目录，默认为当前项目根路径
    # dirpath = os.path.join(app.root_path, '')
    # as_attachment=True 表示下载
    path = getDownLoadPath(path_dir_name)
    print(path)
    print(filename)
    return send_from_directory(path, filename+".zip", as_attachment=True)


@app.route('/createClass', methods=['GET', 'POST'])
def create_class():
    file_name = msg = None
    # {'column': {'age': 'int', 'id': 'String', 'address': 'String', 'name': 'String'}, 'table': 'cc_user'}
    fields = request.form['fields']
    if len(fields) <= 0:
        msg = 'request data json is null!'
    # print(fields)
    j = json.loads(fields, encoding='utf-8')
    class_name = j['class']
    package = j['package']
    db_type = j['type']
    createName = j['createName']
    path, path_dir_name = getPath()
    if len(class_name) <= 0:
        msg = 'className is null!'
    if len(package) <= 0:
        msg = 'package is null'
    if len(db_type) <= 0:
        msg = 'type is null'
    print(class_name + '\n' + package)
    if not msg or len(msg) <= 0:
        d = time.strftime("%Y-%m-%d", time.localtime())
        entity = request.form.get('entity')
        if entity and len(entity) >= 1:
            print('--- create entity class')
            create_entity(createName,class_name, package, j['table'], j['column'], db_type, d)
        mapperXml = request.form.get('mapperXml')
        if mapperXml and len(mapperXml) >= 1:
            print('--- create entity class')
            create_Mapper_xml(createName,class_name, package, j['table'], j['column'], db_type, d)
        mapper = request.form.get('mapper')
        if mapper and len(mapper) >= 1:
            print('--- create mapper class')
            create_mapper(createName,class_name, package, d)
        service = request.form.get('service')
        if service and len(service) >= 1:
            print('--- create service class')
            create_service(createName,class_name, package, d)
        serviceImpl = request.form.get('serviceImpl')
        if serviceImpl and len(serviceImpl) >= 1:
            print('--- create serviceImpl class')
            create_serviceImpl(createName,class_name, package, d)
        dubbo = request.form.get('dubbo')
        if dubbo and len(dubbo) >= 1:
            print('--- create dubbo class')
            create_dubbo(createName,class_name, package, d)
        apiController = request.form.get('apiController')
        if apiController and len(apiController) >= 1:
            print('--- create apiController class')
            create_api_controller(createName,class_name, package, d)
        controller = request.form.get('controller')
        if controller and len(controller) >= 1:
            print('--- create controller class')
            create_controller(createName, class_name, package, d)
        viewList = request.form.get('viewList')
        if viewList and len(viewList) >= 1:
            print('--- create viewList class')
            create_view_list(class_name,package)
        viewAdd = request.form.get('viewAdd')
        if viewAdd and len(viewAdd) >= 1:
            print('--- create viewAdd class')
            create_view_add(class_name, package)
        viewEdit = request.form.get('viewEdit')
        if viewEdit and len(viewEdit) >= 1:
            print('--- create viewEdit class')
            create_view_edit(class_name, package)
        # 打包
        file_name = make_zip(path)

    return render_template('create_class.html', msg=msg, file_name=file_name, path_dir_name=path_dir_name)


# 创建entity
def create_entity(createName,class_name, package, table_name, columns, db_type, date):
    propertys = ''
    methods = ''
    if columns:
        for key in columns.keys():
            propertys += 'private %s %s;' % (columns[key], key) + '\n'
            p1 = '\n    public %s get%s() {\n        return %s;\n}' % (columns[key],key[0].upper() + key[1:], key)
            p2 = '\n    public void set%s(%s %s) {\n        this.%s = %s;\n}' % (key[0].upper() + key[1:], columns[key], key, key, key)
            methods += p1 + '\n' + p2
    c = {'package': package + '.entity',
         'entity_package': package + '.entity.' + class_name,
         'class_name': class_name,
         'table_name': table_name,
         'createName': createName,
         'propertys': propertys,
         'methods': methods,
         'date': date}

    if db_type == 'mysql':
        s = render_template('entity_mysql_templates.html', **c)
        create_java_file(class_name, package + '.entity', s)
    propertys = ''
    methods = ''
    if columns:
        for key in columns.keys():
            propertys += 'private %s %s;' % (columns[key], key) + '\n'
            p1 = '\n    public %s get%s() {\n        return %s;\n}' % (columns[key],key[0].upper() + key[1:], key)
            p2 = '\n    public void set%s(%s %s) {\n        this.%s = %s;\n}' % (key[0].upper() + key[1:], columns[key], key, key, key)
            methods += p1 + '\n' + p2
    c = {'package': package + '.entity',
         'entity_package': package + '.entity.' + class_name,
         'class_name': class_name,
         'table_name': table_name,
         'createName': createName,
         'propertys': propertys,
         'methods': methods,
         'date': date}

    if db_type == 'mysql':
        s = render_template('entity_mysql_templates.html', **c)
        create_java_file(class_name, package + '.entity', s)


# 创建mapper xml
def create_Mapper_xml(createName,class_name, package, table_name, columns, db_type, date):
    mapperResult = ''
    mapperResultValue = ''
    methods = ''
    if columns:
        for key in columns.keys():
            mapperResult += '%s' % (key) + ','
            mapperResultValue += '#{%s' % (key) + '},'
    c = {'package': package + '.mapper',
         'entity_package': package + '.entity.' + class_name,
         'class_name': class_name,
         'table_name': table_name,
         'createName': createName,
         'methods': methods,
         'small_class_name': small_str(class_name),
         'mapperResult': mapperResult,
         'mapperResultValue':mapperResultValue,
         'date': date}

    if db_type == 'mysql':
        t = render_template('entity_mysql_mapper_templates.html', **c)
        create_java_file(class_name, package + '.xml', t, 'Mapper.xml')

# 创建Mapper
def create_mapper(createName,class_name, package, date):
    c = {'package': package + '.Mapper',
         'class_name': class_name,
         'createName': createName,
         'small_class_name': small_str(class_name),
         'entity_package': package + '.entity.' + class_name,
         'date': date}
    s = render_template('mapper_templates.html', **c)
    create_java_file(class_name + 'Mapper', package + '.mapper', s)

# 创建dubbo配置
def create_dubbo(createName,class_name, package, date):
    c = {'package': package + '.service',
         'createName': createName,
         'class_name':class_name,
         'small_class_name': small_str(class_name),
         'date': date}
    s = render_template('dubbo_templates.html', **c)
    create_java_file(class_name + 'Dubbo', package + '.dubboXml', s, '.xml')


# 创建Service
def create_service(createName,class_name, package, date):
    c = {'package': package + '.service',
         'class_name': class_name,
         'createName': createName,
         'small_class_name': small_str(class_name),
         'entity_package': package + '.entity.' + class_name,
         'mapper_package': package + '.mapper.' + class_name + 'Mapper',
         'date': date}
    s = render_template('service_templates.html', **c)
    create_java_file(class_name + 'Service', package + '.service', s)


# 创建ServiceImpl
def create_serviceImpl(createName,class_name, package, date):
    c = {'package': package + '.service.impl',
         'class_name': class_name,
         'createName': createName,
         'small_class_name': small_str(class_name),
         'entity_package': package + '.entity.' + class_name,
         'mapper_package': package + '.mapper.' + class_name + 'Mapper',
         'service_package': package + '.service.' + class_name + 'Service',
         'date': date}
    s = render_template('service_impl_templates.html', **c)
    create_java_file(class_name + 'ServiceImpl', package + '.service.impl', s)

# 创建Controller
def create_controller(createName,class_name, package, date):
    c = {'package': package +'.'+small_str(class_name)+'.controller',
         'class_name': class_name,
         'createName': createName,
         'small_class_name': small_str(class_name),
         'entity_package': package + '.entity.' + class_name,
         'service_package': package + '.service.' + class_name + 'Service',
         'date': date}
    s = render_template('controller_templates.html', **c)
    create_java_file(class_name + 'Controller', package + '.controller', s)

# 创建ApiController
def create_api_controller(createName, class_name, package, date):
    c = {'package': package + '.' + small_str(class_name) + '.apiController',
         'class_name': class_name,
         'createName': createName,
         'small_class_name': small_str(class_name),
         'entity_package': package + '.entity.' + class_name,
         'service_package': package + '.service.' + class_name + 'Service',
         'date': date}
    s = render_template('api_controller_templates.html', **c)
    create_java_file(class_name + 'ApiController', package + '.apiController', s)

# 创建查询页面
def create_view_list(class_name, package):
    c = {
        'class_name': small_str(class_name)}
    s = render_template('view_list_templates.html', ** c)
    create_java_file( class_name.lower()+"_list",package+'.html.list', s,'.ftl')

# 创建添加页面
def create_view_add( class_name,package):
    c = {
         'class_name':small_str(class_name)}
    s = render_template('view_add_templates.html', **c)
    create_java_file( class_name.lower()+"_add",package+'.html.add', s,'.ftl')
# 创建修改页面
def create_view_edit(class_name, package):
    c = {
        'class_name': small_str(class_name)}
    s = render_template('view_edit_templates.html', **c)
    create_java_file(class_name.lower()+"_edit",package+'.html.edit', s,'.ftl')
# 将首字母转换为小写
def small_str(s):
    if len(s) <= 1:
        return s
    return (s[0:1]).lower() + s[1:]


# 创建java文件
def create_java_file(class_name, package, text, suffix='.java'):
    d = time.strftime("%Y%m%d%H%m%s", time.localtime())
    # source_dir = '/opt/wx/generateFile/' + d + '/javaTemplate/'
    source_dir = '/Users/wangjie/' + d + '/'

    if not os.path.exists(source_dir):
        os.makedirs(source_dir)
    dirs = source_dir + package.replace('.', '/') + '/'
    if not os.path.exists(dirs):
        os.makedirs(dirs, 0o777)
    del_file(dirs)
    fd = os.open(dirs + class_name + suffix, os.O_WRONLY | os.O_CREAT)
    os.write(fd, text.encode(encoding="utf-8", errors="strict"))
    os.close(fd)

#删除文件夹下的所有文件和文件夹
def del_file(path):
    for i in os.listdir(path):
        path_file = os.path.join(path, i) # 取文件绝对路径
        if os.path.isfile(path_file):
            os.remove(path_file)
        else:
            del_file(path_file)


# 生成tar.gz压缩包
# def make_targz():
#     file_name = 'javaFiles.tar.gz'
#     d = time.strftime("%Y%m%d%H%m%s", time.localtime())
#     source_dir = '/Users/wangjie/'+d+'/javaTemplate/'
#     if not os.path.exists(source_dir):
#         os.makedirs(source_dir)
#     with tarfile.open(file_name, "w:gz") as tar:
#         tar.add(source_dir, arcname=os.path.basename(source_dir))
#     return file_name

#打包目录为zip文件（未压缩）
def make_zip(source_dir):
    file_name = time.strftime("generateFiles%Y%m%d%H%m%s", time.localtime())
    print(file_name)
    zipf = zipfile.ZipFile(source_dir+file_name+".zip", 'w')
    pre_len = len(os.path.dirname(source_dir))
    for parent, dirnames, filenames in os.walk(source_dir):
      for filename in filenames:
        pathfile = os.path.join(parent, filename)
        arcname = pathfile[pre_len:].strip(os.path.sep)   #相对路径
        zipf.write(pathfile, arcname)
    zipf.close()
    return file_name

def getPath():
    d = time.strftime("%Y%m%d%H%m%s", time.localtime())
    # path = '/opt/wx/generateFile/' + d + '/'
    path = '/Users/wangjie/generateFile/' + d + '/'
    if not os.path.exists(path):
        os.makedirs(path)
    return path, d


def getDownLoadPath(d):
    # path = '/opt/wx/generateFile/' + d + '/'
    path = '/Users/wangjie/generateFile/' + d + '/'
    print(path)
    return path



if __name__ == '__main__':
    app.run()